using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace YatFram.Browser.CssSelector
{
    public class CssSelectors
    {
        public CssSelectors(Selector id, Selector className, Selector name, Selector tag)
        {
            Id = id;
            Class = className;
            Name = name;
            Tag = tag;
        }

        public Selector Id { get; private set; }
        public Selector Class { get; private set; }
        public Selector Name { get; private set; }
        public Selector Tag { get; private set; }

    }

    public static class CssSelectorExtensions
    {
        private const char Space = ' ';
        private static readonly Regex IdRegex = new Regex(@"#((?:[\w\u00c0-\uFFFF_-]|\\.)+)");
        private static readonly Regex ClassRegex = new Regex(@"\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)");
        private static readonly Regex TagRegex = new Regex(@"^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)");
        private static readonly Regex AttrRegex = new Regex(@"\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['""]*)(.*?)\3|)\s*\]");
        private static readonly Regex NameRegex = new Regex(@"\[name=['""]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['""]*\]");

        public static IEnumerable<CssSelectors> ToCssSelectors(this string selectors)
        {
            return selectors.Split(Space).Select(s => ToCssSelector(s));
        }

        public static CssSelectors ToCssSelector(this string s)
        {
            return new CssSelectors(s.ToSelector(IdRegex), s.ToSelector(ClassRegex), s.ToSelector(NameRegex), s.ToSelector(TagRegex));
        }

        private static Selector ToSelector(this string selector, Regex regex)
        {
            var match = regex.Match(selector);
            return match.Success ? new Selector(match.Groups[1].Value) : Selector.NoSelector;
        }
    }
    public class Selector
    {
        public static Selector NoSelector = new Selector(string.Empty);
        private readonly string value;

        public Selector(string value)
        {
            this.value = value;
        }

        public bool Matches()
        {
            return !String.IsNullOrEmpty(value);
        }

        public override string ToString()
        {
            return value;
        }
    }
}